package api

import (
	"context"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"kuangstudy-mall/apis/user-web/jtoken"
	"kuangstudy-mall/apis/user-web/microservices"
	context2 "kuangstudy-mall/apis/user-web/models/context"
	"kuangstudy-mall/apis/user-web/proto"
	"kuangstudy-mall/apis/user-web/utils"
	"kuangstudy-mall/apis/user-web/validation"
	"net/http"
	"strconv"
	"time"
)

type UserApi struct {
	BaseApi
}

/**
 * 查询用户列表
 * @author feige
 * @date 2024-04-08
 * @version 1.0
 * @desc
 */
func (api *UserApi) FindUserList(ctx *gin.Context) {
	pno := ctx.DefaultQuery("pageNo", "1")
	psize := ctx.DefaultQuery("pageSize", "5")
	pageNo, _ := strconv.Atoi(pno)
	pageSize, _ := strconv.Atoi(psize)
	pageInfo := proto.PageInfo{PageNo: uint32(pageNo), PageSize: uint32(pageSize)}
	// rpc调用
	userListResponse, err := microservices.GetNacosUserServiceRpcClient().FindUserList(context.Background(), &pageInfo)
	if err != nil {
		api.handlerGrpcError(err, ctx)
		return
	}
	// grpc 进行远程调用user-srv的服务接口
	api.OK(userListResponse, ctx)
}

/**
 * 根据手机查询用户信息
 * @author feige
 * @date 2024-04-08
 * @version 1.0
 * @desc
 */
func (api *UserApi) GetUserInfoByMobile(ctx *gin.Context) {
	telephone := ctx.DefaultQuery("tel", "")
	// grpc 进行远程调用user-srv的服务接口
	telephoneRequest := proto.TelephoneRequest{}
	telephoneRequest.Telephone = telephone
	userInfoResponse, err := microservices.GetNacosUserServiceRpcClient().GetUserByTelephone(context.Background(), &telephoneRequest)
	if err != nil {
		api.handlerGrpcError(err, ctx)
		return
	}
	api.OK(userInfoResponse, ctx)
}

/**
 * 根据ID查询用户信息
 * @author feige
 * @date 2024-04-08
 * @version 1.0
 * @desc
 */
func (api *UserApi) GetUserInfoById(ctx *gin.Context) {
	uid, _ := ctx.Get("userId")
	userName, _ := ctx.Get("userName")
	fmt.Println(uid.(uint64))
	fmt.Println(userName.(string))
	// grpc 进行远程调用user-srv的服务接口
	id := ctx.DefaultQuery("id", "")
	parseUint, _ := strconv.ParseUint(id, 10, 64)
	// grpc 进行远程调用user-srv的服务接口
	idRequest := proto.IdRequest{}
	idRequest.Id = parseUint
	userInfoResponse, err := microservices.GetNacosUserServiceRpcClient().GetUserById(context.Background(), &idRequest)
	if err != nil {
		api.handlerGrpcError(err, ctx)
		return
	}
	api.OK(userInfoResponse, ctx)
}

// http://localhost:8088/api/v1/user/info/44/32
func (api *UserApi) GetUserInfoById2(ctx *gin.Context) {
	// grpc 进行远程调用user-srv的服务接口
	id := ctx.Param("id")
	parseUint, _ := strconv.ParseUint(id, 10, 64)
	// grpc 进行远程调用user-srv的服务接口
	idRequest := proto.IdRequest{}
	idRequest.Id = parseUint
	userInfoResponse, err := microservices.GetNacosUserServiceRpcClient().GetUserById(context.Background(), &idRequest)
	if err != nil {
		api.handlerGrpcError(err, ctx)
		return
	}
	api.OK(userInfoResponse, ctx)
}

/**
 * 登录
 * @author feige
 * @date 2024-04-08
 * @version 1.0
 * @desc
 */
func (api *UserApi) ToLogin(ctx *gin.Context) {
	userContext := context2.UserContext{}
	err := ctx.ShouldBindJSON(&userContext) // 校验在这里完成
	if err != nil {
		api.FailCodeMsgAny(603, validation.GetErrorMesssages(err, &userContext), ctx)
		return
	}

	// 验证验证码 clear: 代表CaptchaId是否重复利用，如果是false，true就是一次性的
	if !store.Verify(userContext.CaptchaId, userContext.Captcha, false) {
		api.FailCodeMsgAny(603, "验证码错误", ctx)
		return
	}

	// 1:根据手机号码查询对应用户信息
	telephoneRequest := proto.TelephoneRequest{}
	telephoneRequest.Telephone = userContext.Mobile
	userInfoResponse, err := microservices.GetNacosUserServiceRpcClient().GetUserByTelephone(context.Background(), &telephoneRequest)
	if err != nil {
		api.handlerGrpcError(err, ctx)
		return
	}

	// 2: 开始进行密码校验
	passwordVerfiy := utils.PasswordVerfiy(userContext.Password, userInfoResponse.PassWord)
	if passwordVerfiy {
		// 生成token返回
		newJWT := jtoken.NewJWT()
		customClaims := jtoken.CustomClaims{
			ID:          userInfoResponse.Id,
			NickName:    userInfoResponse.NickName,
			AuthorityId: userInfoResponse.Role,
			StandardClaims: jwt.StandardClaims{
				NotBefore: time.Now().Unix(),
				ExpiresAt: time.Now().Unix() + 60*60*24*300,
				Issuer:    "cc",
			},
		}
		// 创建tken
		token, err := newJWT.CreateToken(customClaims)
		if err != nil {
			api.FailCodeMsg(603, "创建token失败", ctx)
			return
		}
		// 返回token和用户信息
		userInfoResponse.PassWord = ""
		api.OKMap(gin.H{"user": userInfoResponse, "token": token}, ctx)
	} else {
		api.FailCodeMsg(603, "用户密码输入有误", ctx)
	}
}

/**
 * 注册
 * @author feige
 * @date 2024-04-08
 * @version 1.0
 * @desc
 */
func (api *UserApi) Reg(ctx *gin.Context) {
	var userRegContext context2.UserRegContext
	err := ctx.ShouldBindJSON(&userRegContext) // 校验在这里完成
	if err != nil {
		api.FailCodeMsgAny(603, validation.GetErrorMesssages(err, &userRegContext), ctx)
		return
	}
	// 密码加密
	createUserRequest := proto.CreateUserRequest{}
	api.CopyProperties(&createUserRequest, userRegContext)
	// gin调用grpc完成接口的注册
	user, err := microservices.GetNacosUserServiceRpcClient().SaveUser(context.Background(), &createUserRequest)
	if err != nil {
		api.handlerGrpcError(err, ctx)
		return
	}

	j := jtoken.NewJWT()
	claims := jtoken.CustomClaims{
		ID:          user.Id,
		NickName:    user.NickName,
		AuthorityId: user.Role,
		StandardClaims: jwt.StandardClaims{
			NotBefore: time.Now().Unix(),                //签名的生效时间
			ExpiresAt: time.Now().Unix() + 60*60*24*300, //30天过期
			Issuer:    "cc",
		},
	}

	token, err := j.CreateToken(claims)
	if err != nil {
		api.FailCodeMsg(http.StatusInternalServerError, "生成token失败", ctx)
		return
	}

	api.OKMap(gin.H{"user": user, "token": token}, ctx)
}
